package canglang.scan.erecord.action;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.InputStream;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import canglang.scan.core.base.action.BaseAction;
import canglang.scan.core.base.model.LabelValue;
import canglang.scan.core.base.pagination.PaginatedListHelper;
import canglang.scan.core.base.properties.AppDefaultProperty;
import canglang.scan.core.base.util.FileUtil;
import canglang.scan.core.base.util.StringUtil;
import canglang.scan.core.base.util.DateUtil;
import canglang.scan.erecord.model.ErecordModel;
import canglang.scan.erecord.service.ErecordManager;
import canglang.scan.erecord.to.SearchTO;
import canglang.scan.erecord.to.DetailTO;
import canglang.scan.user.model.UserModel;
import canglang.scan.user.service.UserManager;

import com.lowagie.text.Document;
import com.lowagie.text.pdf.PdfCopy;
import com.lowagie.text.pdf.PdfImportedPage;
import com.lowagie.text.pdf.PdfReader;
import com.opensymphony.xwork2.util.CreateIfNull;
import com.opensymphony.xwork2.util.Element;

@SuppressWarnings("unchecked")
public class ErecordAction extends BaseAction {

    private static final long serialVersionUID = 4757170559003999499L;

    private static String PDF_ROOT = AppDefaultProperty.getProperty("pdf.store.directory");

    private static String DEFAULT_PRINTER = AppDefaultProperty.getProperty("default.pdf.printer");

    private static String TMP_UPLOAD_FILE = "tmp_upload.pdf";

    private static String TMP_INSERT_FILE = "tmp_insert.pdf";

    private static String TMP_DELETE_FILE = "tmp_delete.pdf";

    private static String TMP_PRINT_FILE = "tmp_print.pdf";


    private ErecordManager erecordManager;

    private UserManager userManager;

    private ErecordModel erecordModel;

    private PaginatedListHelper helper;

    private PaginatedListHelper detailHelper;

    private SearchTO searchTO;

    private int totalPageNum;

    private int total;

    public int getTotal() {
        return total;
    }

    public void setTotal(int total) {
        this.total = total;
    }

    public int getTotalPageNum() {
        return totalPageNum;
    }

    public void setTotalPageNum(int totalPageNum) {
        this.totalPageNum = totalPageNum;
    }

    public ErecordManager getErecordManager() {
        return erecordManager;
    }

    public UserManager getUserManager() {
        return userManager;
    }

    public void setUserManager(UserManager userManager) {
        this.userManager = userManager;
    }

    public void setErecordManager(ErecordManager erecordManager) {
        this.erecordManager = erecordManager;
    }

    public ErecordModel getErecordModel() {
        return erecordModel;
    }

    public void setErecordModel(ErecordModel erecordModel) {
        this.erecordModel = erecordModel;
    }

    public PaginatedListHelper getHelper() {
        return helper;
    }

    public void setHelper(PaginatedListHelper helper) {
        this.helper = helper;
    }

    public PaginatedListHelper getDetailHelper() {
        return detailHelper;
    }

    public void setDetailHelper(PaginatedListHelper detailHelper) {
        this.detailHelper = detailHelper;
    }

    public SearchTO getSearchTO() {
        return searchTO;
    }

    public void setSearchTO(SearchTO searchTO) {
        this.searchTO = searchTO;
    }

    public List getTypeList() {
        List list = new ArrayList();
        String admin = this.getText("label.wenshu.erecord");
        String normalUser = this.getText("label.susong.erecord");
        LabelValue l1 = new LabelValue(admin, "W");
        LabelValue l2 = new LabelValue(normalUser, "S");
        list.add(l1);
        list.add(l2);
        return list;
    }

    @Element(value = ErecordModel.class)
    @CreateIfNull(value = true)
    public List<Object> getResultList() {
        return helper != null ? helper.getList() : null;
    }

    public void setResultList(List<Object> alist) {
        if (helper == null)
            helper = new PaginatedListHelper();
        helper.setList(alist);
    }

    @Element(value = DetailTO.class)
    @CreateIfNull(value = true)
    public List<Object> getDetailResultList() {
        return detailHelper != null ? detailHelper.getList() : null;
    }

    public void setDetailResultList(List<Object> alist) {
        if (detailHelper == null)
            detailHelper = new PaginatedListHelper();
        detailHelper.setList(alist);
    }

    public String searchErecord() {
        if (searchTO == null) {
            searchTO = new SearchTO();
        }

        if (helper == null) {
            helper = new PaginatedListHelper();
            helper.setSortCriterion("RECORD_NAME");


        }
        helper = erecordManager.searchErecord(helper, searchTO);
        return SUCCESS;
    }

    public String deleteErecord() {
        String pass = ((UserModel) this.getRequest().getSession().getAttribute("user")).getUserPassword();
        if (!pass.equals(erecordModel.getDeletePassword())) {
            this.addActionError(AppDefaultProperty.getProperty("label.password.wrong"));
            return searchErecord();
        }
        for (int i = 0; i < helper.getList().size(); i++) {
            ErecordModel u = (ErecordModel) helper.getList().get(i);
            if (u != null && !StringUtil.convertEmpty2Null(u.getSelectId()).equalsIgnoreCase("")
                    && !StringUtil.convertEmpty2Null(u.getSelectId()).equalsIgnoreCase("false")) {
                erecordManager.deleteErecord(Integer.parseInt(u.getSelectId()));
            }
        }
        this.saveMessage(AppDefaultProperty.getProperty("label.delete.successful"));
        return searchErecord();
    }

    public String searchDetail() throws Exception {
        String userId = ((UserModel) this.getRequest().getSession().getAttribute("user")).getUserId();
        Document document;
        PdfReader reader;
        if (detailHelper == null) {
            detailHelper = new PaginatedListHelper();
        }
        File dir = new File(PDF_ROOT + userId);
        File file = new File(dir, TMP_UPLOAD_FILE);
        byte[] b = FileUtil.convertToByte(file);
        document = new Document((new PdfReader(b).getPageSize(1)));
        document.open();
        reader = new PdfReader(b);
        total = reader.getNumberOfPages();
        reader.close();
        document.close();
        detailHelper.setFullListSize(total);
        DetailTO detail;
        List list = new ArrayList();
        for (int i = 1 + detailHelper.getObjectsPerPage() * (detailHelper.getPageNumber() - 1); i <= detailHelper.getObjectsPerPage() * detailHelper.getPageNumber(); i++) {
            if (i <= detailHelper.getFullListSize()) {
                detail = new DetailTO();
                detail.setPageNo(i);
                list.add(detail);
            } else {
                break;
            }
        }
        detailHelper.setList(list);
        return SUCCESS;
    }

    public String addErecord() throws Exception {
        String userId = ((UserModel) this.getRequest().getSession().getAttribute("user")).getUserId();
        erecordModel.setUploadContent(FileUtil.convertToByte(erecordModel.getUpload()));
        File dir = new File(PDF_ROOT + userId);
        if (!dir.exists()) dir.mkdir();
        File file = new File(dir, TMP_UPLOAD_FILE);
        if (file.exists()) file.delete();
        file.createNewFile();
        FileUtil.copyFile(erecordModel.getUpload(), file);
        erecordModel.setCreateId(userId);
        erecordModel.setUpdateId(userId);
        Date date = DateUtil.getDate();
        erecordModel.setCreateDt(date);
        erecordModel.setUpdateDt(date);
        erecordModel = erecordManager.addErecord(erecordModel);
        this.saveMessage(AppDefaultProperty.getProperty("label.add.successful"));
        return searchDetail();
    }

    public String viewErecord() throws Exception {
        String userId = ((UserModel) this.getRequest().getSession().getAttribute("user")).getUserId();
        String selectId = erecordModel.getSelectId();
        erecordModel = erecordManager.getErecord(Integer.parseInt(selectId));
        File dir = new File(PDF_ROOT + userId);
        if (!dir.exists())
            dir.mkdir();
        File file = new File(dir, TMP_UPLOAD_FILE);
        if (file.exists())
            file.delete();
        file.createNewFile();
        FileUtil.createFile(erecordModel.getUploadContent(), file);
        return searchDetail();
    }

    public String saveErecord() throws Exception {
        String userId = ((UserModel) this.getRequest().getSession().getAttribute("user")).getUserId();
        File dir = new File(PDF_ROOT + userId);
        File file = new File(dir, TMP_UPLOAD_FILE);
        erecordModel.setUploadContent(FileUtil.convertToByte(file));
        erecordModel.setUpdateId(userId);
        erecordModel.setUpdateDt(DateUtil.getDate());
        erecordModel = erecordManager.saveErecord(erecordModel);
        this.saveMessage(AppDefaultProperty.getProperty("label.save.successful"));
        return searchDetail();
    }

    public String addPdfDetail() throws Exception {
        String userId = ((UserModel) this.getRequest().getSession().getAttribute("user")).getUserId();
        int pageNum = Integer.parseInt(erecordModel.getSelectPageNum());
        File fullFile = new File((PDF_ROOT + userId), TMP_UPLOAD_FILE);
        File tmpFile = new File((PDF_ROOT + userId), TMP_INSERT_FILE);
        if (tmpFile.exists()) tmpFile.delete();
        tmpFile.createNewFile();
        Document document = null;
        PdfReader reader = null;
        PdfCopy copy;
        PdfImportedPage page;
        try {
            document = new Document((new PdfReader(FileUtil.convertToByte(fullFile)).getPageSize(1)));
            reader = new PdfReader(FileUtil.convertToByte(fullFile));
            int n;
            copy = new PdfCopy(document, new FileOutputStream(tmpFile));
            document.open();
            for (int i = 1; i < pageNum; i++) {
                document.newPage();
                page = copy.getImportedPage(reader, i);
                copy.addPage(page);
            }

            reader = new PdfReader(FileUtil.convertToByte(erecordModel.getInsert()));
            n = reader.getNumberOfPages();

            for (int i = 1; i <= n; i++) {
                document.newPage();
                page = copy.getImportedPage(reader, i);
                copy.addPage(page);
            }
            reader = new PdfReader(FileUtil.convertToByte(fullFile));
            n = reader.getNumberOfPages();
            for (int i = pageNum; i <= n; i++) {
                document.newPage();
                page = copy.getImportedPage(reader, i);
                copy.addPage(page);
            }
            if (reader != null)
                reader.close();
            if (document != null)
                document.close();
            fullFile.delete();
            tmpFile.renameTo(fullFile);
            return SUCCESS;
        } catch (Exception e) {
            throw e;
        } finally {
            if (reader != null)
                reader.close();
            if (document != null)
                document.close();
        }
    }

    public String viewPdfDetail() throws Exception {
        int selectNum = Integer.parseInt(erecordModel.getSelectPageNum());
        String userId = ((UserModel) this.getRequest().getSession().getAttribute("user")).getUserId();
        Document document = null;
        PdfReader reader = null;
        File fullFile = new File((PDF_ROOT + userId), TMP_UPLOAD_FILE);
        try {
            document = new Document((new PdfReader(FileUtil.convertToByte(fullFile)).getPageSize(1)));
            String sysTime = getCurrentTimestamp().toString();
            sysTime = sysTime.replaceAll(":", "_");
            sysTime = sysTime.replaceAll("-", "_");
            sysTime = sysTime.replaceAll(" ", "_");
            String fileName = "page_" + selectNum + sysTime + ".pdf";
            String fullName = (PDF_ROOT + userId) + "/" + fileName;
            File file = new File(fullName);
            if (file.exists())
                file.delete();
            file.createNewFile();
            PdfCopy copy = new PdfCopy(document, new FileOutputStream(file));
            document.open();
            reader = new PdfReader(FileUtil.convertToByte(fullFile));
            totalPageNum = reader.getNumberOfPages();
            if (selectNum > totalPageNum) selectNum = totalPageNum;
            document.newPage();
            PdfImportedPage page = copy.getImportedPage(reader, selectNum);
            copy.addPage(page);
            System.out.println(this.getRequest().getServerName());
            this.getRequest().setAttribute("erecordDetail",
                    ("http://" + this.getRequest().getServerName() + ":8080/scan/pdf/" + userId + "/" + fileName));
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (reader != null)
                reader.close();
            if (document != null)
                document.close();
        }
        return SUCCESS;
    }

    public String deletePdfDetail() throws Exception {
        String pass = ((UserModel) this.getRequest().getSession().getAttribute("user")).getUserPassword();
        if (!pass.equals(erecordModel.getDeletePassword())) {
            this.addActionError(AppDefaultProperty.getProperty("label.password.wrong"));
            return searchDetail();
        }
        String userId = ((UserModel) this.getRequest().getSession().getAttribute("user")).getUserId();
        int pageNum = Integer.parseInt(erecordModel.getSelectPageNum());
        Document document = null;
        PdfReader reader = null;
        PdfCopy copy;
        PdfImportedPage page;
        try {
            File fullFile = new File((PDF_ROOT + userId), TMP_UPLOAD_FILE);
            File tmpFile = new File((PDF_ROOT + userId), TMP_DELETE_FILE);
            if (tmpFile.exists()) tmpFile.delete();
            tmpFile.createNewFile();
            document = new Document((new PdfReader(FileUtil.convertToByte(fullFile)).getPageSize(1)));
            reader = new PdfReader(FileUtil.convertToByte(fullFile));
            int n = reader.getNumberOfPages();
            copy = new PdfCopy(document, new FileOutputStream(tmpFile));
            document.open();
            for (int i = 1; i <= n; i++) {
                if (i == pageNum) continue;
                document.newPage();
                page = copy.getImportedPage(reader, i);
                copy.addPage(page);
            }
            reader.close();
            document.close();
            fullFile.delete();
            tmpFile.renameTo(fullFile);
            if (!StringUtil.isNullOrBlank(erecordModel.getPrintArray())) {
                StringBuffer array = null;
                String[] arr = erecordModel.getPrintArray().split(";");
                for (int i = 0; i < arr.length; i++) {
                    if (pageNum > Integer.parseInt(arr[i])) {
                        if (array == null) {
                            array = new StringBuffer("");
                            array.append(arr[i]);
                        } else {
                            array.append(";").append(arr[i]);
                        }
                    } else if (pageNum == Integer.parseInt(arr[i])) {
                        continue;
                    } else {
                        int j = Integer.parseInt(arr[i]) - 1;
                        if (array == null) {
                            array = new StringBuffer("");
                            array.append(String.valueOf(j));
                        } else {
                            array.append(";").append(String.valueOf(j));
                        }
                    }
                }
                if (array == null) {
                    erecordModel.setPrintArray("");
                } else {
                    erecordModel.setPrintArray(array.toString());
                }
            }
            return searchDetail();
        } catch (Exception e) {
            throw e;
        } finally {
            if (reader != null)
                reader.close();
            if (document != null)
                document.close();
        }
    }

    public String printAll() throws Exception {
        InputStream instream;
        FileOutputStream fos;
        PdfReader reader = null;
        Document document = null;
        PdfCopy writer = null;
        String userId = ((UserModel) this.getRequest().getSession().getAttribute("user")).getUserId();
        try {
            document = new Document();
            instream = FileUtil.getTempInputStream(PDF_ROOT + userId + "/" + TMP_UPLOAD_FILE);
            reader = new PdfReader(instream);
            File tmpFile = new File(PDF_ROOT + userId + "/" + TMP_PRINT_FILE);
            if (tmpFile.exists()) tmpFile.delete();
            tmpFile.createNewFile();
            fos = new FileOutputStream(tmpFile);
            writer = new PdfCopy(document, fos);
            document.open();
            writer.addJavaScript("this.print(false);", false);
            int numOfPages = reader.getNumberOfPages();
            for (int idxi = 0; idxi < numOfPages; idxi++) {
                PdfImportedPage page = writer.getImportedPage(reader, idxi + 1);
                writer.addPage(page);
            }
            writer.close();
            reader.close();
            document.close();
            String scheme = this.getRequest().getScheme(); // protocol
            String serverName = this.getRequest().getServerName(); // host
            int serverPort = this.getRequest().getServerPort(); // port
            String contextPath = this.getRequest().getContextPath(); // context
            StringBuffer buf = new StringBuffer();
            buf.append(scheme).append("://").append(serverName).append(":").append(serverPort).append("/");
            buf.append(contextPath).append("/pdf/").append(userId).append("/").append(TMP_PRINT_FILE);
            this.getRequest().setAttribute("printUri", buf.toString());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (writer != null) writer.close();
            if (reader != null) reader.close();
            if (document != null) document.close();
        }
        erecordModel.setPrintArray("");
        return searchDetail();
    }

    public String printSelect() throws Exception {
        String userId = ((UserModel) this.getRequest().getSession().getAttribute("user")).getUserId();
        String selectPage = erecordModel.getPrintArray();
        String[] arr = selectPage.split(";");
        ArrayList list = new ArrayList();
        File fullFile = new File((PDF_ROOT + userId), TMP_UPLOAD_FILE);
        File tmpFile = new File((PDF_ROOT + userId), TMP_PRINT_FILE);
        if (tmpFile.exists()) tmpFile.delete();
        tmpFile.createNewFile();
        Document document = null;
        PdfReader reader = null;
        PdfCopy copy;
        PdfImportedPage page;
        for (int i = 0; i < arr.length; i++) {
            if (!list.contains(arr[i]))
                list.add(arr[i]);
        }
        try {
            document = new Document((new PdfReader(FileUtil.convertToByte(fullFile)).getPageSize(1)));
            reader = new PdfReader(FileUtil.convertToByte(fullFile));
            copy = new PdfCopy(document, new FileOutputStream(tmpFile));
            document.open();
            document.open();
            copy.addJavaScript("this.print(false);", false);
            for (int i = 0; i < list.size(); i++) {
                String selectNum = (String) list.get(i);
                int num = Integer.parseInt(selectNum);
                page = copy.getImportedPage(reader, num);
                copy.addPage(page);
            }
            reader.close();
            document.close();
            String scheme = this.getRequest().getScheme(); // protocol
            String serverName = this.getRequest().getServerName(); // host
            int serverPort = this.getRequest().getServerPort(); // port
            String contextPath = this.getRequest().getContextPath(); // context
            StringBuffer buf = new StringBuffer();
            buf.append(scheme).append("://").append(serverName).append(":").append(serverPort).append("/");
            buf.append(contextPath).append("/pdf/").append(userId).append("/").append(TMP_PRINT_FILE);
            this.getRequest().setAttribute("printUri", buf.toString());
            erecordModel.setPrintArray("");
            return searchDetail();
        } catch (Exception e) {
            throw e;
        } finally {
            if (reader != null)
                reader.close();
            if (document != null)
                document.close();
        }
    }


    public Timestamp getCurrentTimestamp() {
        return new Timestamp(new Date().getTime());
    }

    public String download() throws Exception {
        try {
            String userId = ((UserModel) this.getRequest().getSession().getAttribute("user")).getUserId();
            getResponse().reset();
            getResponse().setHeader("Content-Disposition", "attachment; filename=\"" + new String("filename.pdf".getBytes("gb2312"), "ISO8859-1"));
            getResponse().setContentType("application/download");
            byte[] content = FileUtil.convertToByte(new File(AppDefaultProperty.getProperty("pdf.store.directory") + userId + "\\" + TMP_UPLOAD_FILE));
            getResponse().setContentLength(content.length);
            OutputStream out = getResponse().getOutputStream();
            out.write(content);
            out.flush();
        } catch (Exception e) {
            System.out.println(e);
            throw e;
        }

        return NONE;
    }
}
